package mm.chenchen.common.utils;

import io.minio.*;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * minio工具类
 * 2021/4/20
 *
 * @author ccw 564697100@qq.com
 */
@Slf4j
public class MinioUtil {

    public final static String IMAGE_BUCKET = "image";
    public final static String VIDEO_BUCKET = "video";
    public final static String DOC_BUCKET = "doc";
    public final static String OTHER_BUCKET = "other";


    private MinioUtil() {
    }


    public static String addBucket(MinioClient minioClient, String bucket) {
        MakeBucketArgs.Builder builder = MakeBucketArgs.builder();
        builder.bucket(bucket);
        MakeBucketArgs makeBucketArgs = builder.build();
        try {
            minioClient.makeBucket(makeBucketArgs);
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidBucketNameException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (RegionConflictException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
        return "success";
    }


    public static String upload(MinioClient minioClient, String bucket, InputStream in, String fileName) {
        try {
            //文件上传到minio上的Name把文件后缀带上，不然下载出现格式问题
            BucketExistsArgs.Builder bucketExistsArgs = BucketExistsArgs.builder();
            bucketExistsArgs.bucket(bucket);
            minioClient.bucketExists(bucketExistsArgs.build());
            if (!minioClient.bucketExists(bucketExistsArgs.build())) {
                addBucket(minioClient, bucket);
            }

            //创建头部信息
            Map<String, String> headers = new HashMap<>(1 << 2);
            //添加自定义内容类型
            headers.put("Content-Type", "application/octet-stream");
            //添加存储类
            headers.put("X-Amz-Storage-Class", "REDUCED_REDUNDANCY");
            //添加自定义/用户元数据
            Map<String, String> userMetadata = new HashMap<>(1 << 2);
            userMetadata.put("My-Project", "Project One");
            //上传
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(bucket).object(fileName).stream(
                            in, in.available(), -1)
                            .headers(headers)
                            .userMetadata(userMetadata)
                            .build());
            in.close();
            return fileName;
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    public static InputStream download(MinioClient minioClient, String bucket, String fileName) {
        try {
            InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(fileName).build());
//            byte[] buf = new byte[1024];
//            int bytesRead;
//            while ((bytesRead = stream.read(buf, 0, buf.length)) >= 0) {
//                System.out.println(new String(buf, 0, bytesRead, StandardCharsets.UTF_8));
//            }
//            stream.close();
            return stream;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String delete(MinioClient minioClient, String bucket, String fileName) {
        try {
            log.info("minio删除 {} 下的文件: {} ", bucket, fileName);
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(fileName).build());
            return "success";
        } catch (Exception e) {
            log.info("minio删除 {} 下的文件: {} 失败异常 !!!!!!!!!!!!", bucket, fileName);
            e.printStackTrace();
            return e.getMessage();
        }
    }


}
